package com.customization.unionpay.market.service.impl;


import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import com.customization.unionpay.market.dao.ActivityApplicationDao;
import com.customization.unionpay.market.dao.MarketActivityEventDao;
import com.customization.unionpay.market.dao.WorkflowRequestbaseDao;
import com.customization.unionpay.market.service.CheckReimbursementWorkflowService;
import com.customization.unionpay.market.service.MarketActivityEventService;
import com.customization.unionpay.market.service.MarketPersonalTaxWorkflowService;
import com.customization.unionpay.market.service.MarketingDailyService;
import com.customization.unionpay.market.util.FormDataUtils;
import com.customization.unionpay.market.util.FormUtil;
import com.customization.unionpay.market.dao.ApplicationAdjustmentDao;
import com.customization.unionpay.market.util.FormDataUtil;
import com.engine.budget.service.impl.BusinessBudgetServiceImpl;
import weaver.backup.logging.Logger;
import weaver.backup.logging.LoggerFactory;
import weaver.hrm.User;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 营销活动事项
 */
public class MarketActivityEventServiceImpl implements MarketActivityEventService {

    private static final Logger log = LoggerFactory.getLogger(MarketActivityEventServiceImpl.class);


    /**
     * 1、进行内部校验，校验规则:
     * 一、根据授权码查询营销活动事项台账，找到对应台账后，查看明细表每条明细数据的字段已入账金额的数据等于已核销金额的数据，有一条明细不相等校验不通过。
     * 二、根据授权码查询营销日报表台账，找到日报流水类型和状态，
     * 当日报流水类型为异常数据,状态为未确认、已确认未入账、异常数据、已结项数据、入账中和入账失败，满足其中个条件校验不通过。
     * 三、根据授权码向云闪付营销平台发送查询授权码状态请求，状态为核销校验通过，其他状态校验不通过。据授权码查询核销报账单，获取发票类型和是否缴纳个税，
     * 如果发票类型为活动交易流水和完税凭证或者是否缴纳个税为是，满足以上任意条件需要查看是否发起营销个税计提单，如果没有发起，拼接数据发起营销个税计提单，本次校验不通过。
     * 如果已经发起，查看是否审批结束，审批未结束，校验不通过
     * 2、调用闪付营销平台发送查询授权码状态财务结项时的校验，判断校验是否通过
     *
     * @param selectId
     * @param userId
     * @return
     */

    @Override
    public String financialMattersOver(List<JSONObject> selectId, User userId) {
        StringBuilder result = new StringBuilder();
        try {
            List<String> ids = new ArrayList<>();
            List<String> bdhList = new ArrayList<>();
            for (JSONObject obj : selectId) {
                if (obj.containsKey("id") && obj.containsKey("bdh")) {
                    ids.add(obj.getString("id"));
                    bdhList.add(obj.getString("bdh"));
                } else {
                    System.out.println("JSONObject 中缺少字段");
                }
            }
            com.customization.unionpay.market.dao.MarketActivityEventDao marketActivityEventDao = new MarketActivityEventDao();
            List<JSONObject> marketActivityEventList = marketActivityEventDao.queryByIds(ids);

            //如果查询出来的数据不存在 营销活动事项都不存在 不通过
            if (CollectionUtil.isEmpty(marketActivityEventList)) {
                return result.append("校验不通过:营销活动事项不存在").toString();
            } else {
                //先校验是否存在金额不对等的
                List<JSONObject> noPass = marketActivityEventList.stream().
                        filter(o -> o.getFloatValue("yrzje") != o.getFloatValue("yhxje")).collect(Collectors.toList());
                if (CollectionUtil.isNotEmpty(noPass)) {
                    return result.append("校验不通过:已入账金额与已核销金额不一致").toString();
                }
                //查询营销日报表台账 流水类型为异常数据状态为未确认、已确认未入账、异常数据、已结项数据、入账中和入账失败
                MarketingDailyService marketDailyService = new MarkertingDailyServiceImpl();
                //获取所有的授权码
                List<String> sqms = marketActivityEventList.stream().
                        map(o -> o.getString("yxpthdsqm")).collect(Collectors.toList());
                //查询授权码的营销日报
                List<JSONObject> marketDailyList = marketDailyService.queryBySqm(sqms);
                //查询营销日报表的状态枚举
                List<JSONObject> marketDailyZtItem = FormDataUtil.getSelectItem(com.customization.unionpay.market.util.FormUtil.UF_YXRBBTZ_ID, "zt", null);
                //查询营销日报表的日报流水枚举
                List<JSONObject> markerDailyRblslxItem = FormDataUtil.getSelectItem(com.customization.unionpay.market.util.FormUtil.UF_YXRBBTZ_ID, "rblslx", null);
                //要校验的状态枚举id 未确认、已确认未入账、入账中和入账失败
                List<Integer> marketDailyZtItemId = marketDailyZtItem.stream().filter(o -> {
                            String name = o.getString("name");
                            String[] noPassName = new String[]{"未确认", "已确认未入账", "入账中", "入账失败"};
                            return Arrays.asList(noPassName).contains(name);
                        }
                ).map(o -> o.getInteger("value")).collect(Collectors.toList());
                //要校验的状态枚举id 异常数据
                List<Integer> markerDailyRblslxItemId = markerDailyRblslxItem.stream().filter(o -> {
                            String name = o.getString("name");
                            String[] noPassName = new String[]{"异常数据"};
                            return Arrays.asList(noPassName).contains(name);
                        }
                ).map(o -> o.getInteger("value")).collect(Collectors.toList());
                //没通过的营销日报表
                List<JSONObject> noPassMarketDailyList = marketDailyList.stream().
                        filter(o -> {
                            Integer zt = o.getInteger("zt");
                            Integer rblslx = o.getInteger("rblslx");
                            return marketDailyZtItemId.contains(zt) || markerDailyRblslxItemId.contains(rblslx);
                        }).collect(Collectors.toList());
                if (CollectionUtil.isNotEmpty(noPassMarketDailyList)) {
                    return result.append("校验不通过:营销日报表台账状态不符合").toString();
                }

//                boolean sqmCheck = true;
//                String ysfResult = CloudFlashPaymentUtils.batchQueryByBudgetAuthCode(sqms);
//                log.info("云闪付授权码核销状态结果:" + ysfResult);
//
//                JSONObject ysfResultJson = JSONObject.parseObject(ysfResult);
//                if ("200".equals(ysfResultJson.getString("stateCode"))) {
//                    JSONArray ysfData = ysfResultJson.getJSONArray("data");
//                    log.info("云闪付数据" + ysfData);
//                    for (int i = 0; i < ysfData.size(); i++) {
//                        JSONObject ysfInfo = ysfData.getJSONObject(i);
//                        if (!"核销校验通过".equals(ysfInfo.getString("stat"))) {
//                            return result.append("校验不通过:该授权码未核销").toString();
//                        }
//                    }
//                }
                //查询核销报账单发票类型和是否缴纳个税，如果发票类型为活动交易流水和完税凭证或者是否缴纳个税为是
                CheckReimbursementWorkflowService checkReimbursementWorkflowService = new CheckReimbursementWorkflowServiceImpl();
                List<JSONObject> checkReimbursement = checkReimbursementWorkflowService.getCheckReimbursementWorkflowBySqm(sqms);
                if (CollectionUtil.isEmpty(checkReimbursement)) {
                    return result.append("校验不通过:未查询到核销报账单信息").toString();
                }
                //查询核销报账单的发票类型枚举
                List<JSONObject> checkReimbursementFplxItem = FormDataUtil.getSelectItem(com.customization.unionpay.market.util.FormUtil.CHECK_REIMBURSEMENT_ID, "fplx", null);
                //查询核销报账单的是否缴纳个税枚举
                List<JSONObject> checkReimbursementSfjngsItem = FormDataUtil.getSelectItem(com.customization.unionpay.market.util.FormUtil.CHECK_REIMBURSEMENT_ID, "sfjngs", null);
                //发票类型为"活动交易流水","完税凭证"ID集合
                List<Integer> filterFplxItemId = checkReimbursementFplxItem.stream().filter(o -> {
                    List<String> fplxFilter = Arrays.asList(new String[]{"活动交易流水", "完税凭证"});
                    return fplxFilter.contains(o.getString("name"));
                }).map(o -> o.getInteger("value")).collect(Collectors.toList());
                //是否缴纳个税为是的ID集合
                List<Integer> filterSfjngsItemId = checkReimbursementSfjngsItem.stream().filter(o -> {
                    List<String> sfjngsFilter = Arrays.asList(new String[]{"是"});
                    return sfjngsFilter.contains(o.getString("name"));
                }).map(o -> o.getInteger("value")).collect(Collectors.toList());
                MarketPersonalTaxWorkflowService marketPersonalTaxWorkflowService = new MarketPersonalTaxWorkflowServiceImpl();
                //获取营销个税计提单的列表
//                List<JSONObject> marketPersonalTaxList = marketPersonalTaxWorkflowService.queryMarketPersonalTaxWorkflowBySqm(sqms);
//                //营销个税计提单根据核销码分组
//                Map<String, List<JSONObject>> marketPersonalTaxMap = marketPersonalTaxList.stream()
//                        .collect(Collectors.groupingBy(o -> o.getString("yxpthdsqm")));
//
//                for (JSONObject o : checkReimbursement) {
//                    if (filterFplxItemId.contains(o.getInteger("fplx")) || filterSfjngsItemId.contains(o.getInteger("sfjngs"))) {
//                        //不存在营销个税提计单 就得发起
//                        List<JSONObject> list = marketPersonalTaxMap.get(o.getString("yxpthdm"));
//                        if (CollectionUtil.isEmpty(list)) {
//                            //提供核销报账单的数据 创建营销个税提计单
//                            marketPersonalTaxWorkflowService.createMarketPersonalTaxWorkflow(userId, o);
//                            return result.append("核验不通过:未发起营销个税提计单！已自动发起营销个税提计单").toString();
//                        } else {
//                            //存在营销个税提计单
//                            for (JSONObject jsonObject : list) {
//                                //营销个税提计单还没归档
//                                if (!"3".equals(jsonObject.getString("currentnodetype"))) {
//                                    return result.append("核验不通过:对应营销个税提计单未归档").toString();
//                                }
//                            }
//                        }
//                    }
//                }
            }

            ApplicationAdjustmentDao applicationAdjustmentDao = new ApplicationAdjustmentDao();
            List<JSONObject> adjustmentList = applicationAdjustmentDao.queryByBdhs(bdhList);
            com.customization.unionpay.market.dao.WorkflowRequestbaseDao workflowRequestbaseDao = new com.customization.unionpay.market.dao.WorkflowRequestbaseDao();
            BusinessBudgetServiceImpl businessBudgetService = new BusinessBudgetServiceImpl();
            com.customization.unionpay.market.dao.ActivityApplicationDao activityApplicationDao = new ActivityApplicationDao();
            List<JSONObject> applicationList = activityApplicationDao.queryByBdhs(bdhList);
            if (CollectionUtil.isNotEmpty(adjustmentList)) {
                processAdjustmentList(adjustmentList, workflowRequestbaseDao, businessBudgetService, userId);
            } else if( CollectionUtil.isNotEmpty(applicationList)){
                if (CollectionUtil.isNotEmpty(applicationList)) {
                    processApplicationList(applicationList, workflowRequestbaseDao, businessBudgetService, userId);
                }
            }
            result.append("校验通过");
            return result.toString();
        } catch (Exception e) {
            log.error("核验营销个税提计单异常", e);
        }
        return result.append("核验不通过:核验营销个税提计单异常").toString();
    }

    private void processAdjustmentList(List<JSONObject> adjustmentList, com.customization.unionpay.market.dao.WorkflowRequestbaseDao workflowRequestbaseDao, BusinessBudgetServiceImpl businessBudgetService, User userId) {
        JSONObject insertJson = new JSONObject();
        for (JSONObject o : adjustmentList) {
            String ywlx = FormDataUtils.getItemName(FormUtil.APPLICATION_ADJUSTMENT_ID, "ywlx", o.getString("ywlx"));
            if ("营销平台事项申请金额调增单".equals(ywlx)) {
                prepareParams(insertJson, o, workflowRequestbaseDao);
            }
            insertJson.put("je", o.getString("bcdzje"));
            HashMap<String, Object> otherMap = new HashMap<>();
            otherMap.put("logId", o.getString("requestid"));
            otherMap.put("user", userId);
            Map<String, Object> params = new HashMap<>();
            params.put("params", Arrays.asList(insertJson));
            businessBudgetService.execBudget(params, otherMap);
        }
    }

    private void processApplicationList(List<JSONObject> applicationList, com.customization.unionpay.market.dao.WorkflowRequestbaseDao workflowRequestbaseDao, BusinessBudgetServiceImpl businessBudgetService, User userId) {
        JSONObject insertJson = new JSONObject();
        for (JSONObject o : applicationList) {
            prepareParams(insertJson, o, workflowRequestbaseDao);
            insertJson.put("je", o.getString("nbczje"));
            HashMap<String, Object> otherMap = new HashMap<>();
            otherMap.put("logId", o.getString("requestid"));
            otherMap.put("user", userId);
            Map<String, Object> params = new HashMap<>();
            params.put("params", Arrays.asList(insertJson));
            businessBudgetService.execBudget(params, otherMap);
        }
    }

    private void prepareParams(JSONObject insertJson, JSONObject o, WorkflowRequestbaseDao workflowRequestbaseDao) {
        insertJson.put("ysxm", o.getString("PROJECT_CODE"));
        insertJson.put("yskm", o.getString("yskm"));
        insertJson.put("zxdw", o.getString("yszrzx"));
        insertJson.put("ysqjn", o.getString("ysqjn"));
        insertJson.put("zxdjh", o.getString("bdh"));
        insertJson.put("yskzq", o.getString("yskzq"));
        List<JSONObject> list = workflowRequestbaseDao.queryById(Integer.parseInt(o.getString("requestid")));
        String zxrq = list.get(0).getString("zxrq");
        insertJson.put("zxrq", zxrq);
        insertJson.put("zhdjlx", o.getString("ywlx"));
        insertJson.put("bzr", o.getString("sqr"));
        insertJson.put("lyxt", o.getString("lyxt"));
        insertJson.put("sm", o.getString("sm"));
        insertJson.put("bzbm", o.getString("bzbm"));
        insertJson.put("bzgs", o.getString("bzgs"));
        insertJson.put("jjsx", o.getString("jjsx"));
        insertJson.put("zl", "SFZY");
    }


}
